/**
 * 客户端测试4437接口脚本（赤壁下注）
 * 流程对齐 test-code-1336.js：HTTP登录 → WebSocket连接 → 选择角色 → 查询游戏信息 → 测试下注
 */

const http = require('http');
const WebSocket = require('ws');

// 测试配置（与1336保持一致）
const CONFIG = {
    server: {
        host: 'localhost',
        port: 3000,
        protocol: 'http'
    },
    testUser: {
        mobile: '17091271111',
        password: '123456',
        passwordHash: 'e10adc3949ba59abbe56e057f20f883e'
    },
    testCharacter: {
        name: '测试角色',
        sex: 1,
        roleType: 1,
        headIndex: 2
    }
};

class Code4437Tester {
    constructor() {
        this.token = null;
        this.userId = null;
        this.ws = null;
        this.characters = [];
        this.selectedCharacter = null;
        this.currentInfo = null;
    }

    async runTest() {
        console.log('🏯 开始客户端4437接口测试(赤壁下注)...\n');
        console.log('测试目标：HTTP登录 → WebSocket连接 → 选择角色 → 查询赤壁信息 → 测试下注\n');
        try {
            await this.testHttpLogin();
            await this.testWebSocketConnection();
            await this.testQueryCharacters();

            if (this.characters.length === 0) {
                await this.testCreateCharacter();
                await this.testQueryCharacters();
            }

            await this.testSelectCharacter();
            await this.testQueryChibiInfo();
            await this.testChibiBet();
            await this.testQueryChibiInfo(true);
            await this.testDisconnect();
        } catch (error) {
            console.error('❌ 测试过程中发生错误:', error.message);
        }
    }

    async testHttpLogin() {
        console.log('🔐 步骤1: HTTP登录测试...');
        try {
            await this.registerUser();
            const loginData = await this.makeHttpRequest('/user-service/user/login', 'POST', {
                mobile: CONFIG.testUser.mobile,
                pwd: CONFIG.testUser.passwordHash
            });
            if (loginData.code === 0 && loginData.data) {
                this.userId = loginData.data.userId;
                this.token = loginData.data.accessToken;
                console.log(`✅ 登录成功: userId=${this.userId}`);
            } else {
                throw new Error(`登录失败: ${loginData.msg || '未知错误'}`);
            }
        } catch (error) {
            console.log('❌ 登录失败:', error.message);
            throw error;
        }
    }

    async registerUser() {
        try {
            const res = await this.makeHttpRequest('/user-service/user/register', 'POST', {
                mobile: CONFIG.testUser.mobile,
                pwd: CONFIG.testUser.passwordHash,
                captcha: '123456'
            });
            console.log('📝 用户注册成功', res);
        } catch (error) {
            if (error.message.includes('MOBILE_EXISTS') || error.message.includes('已存在')) {
                console.log('👤 用户已存在，跳过注册');
            } else {
                console.log('⚠️ 注册失败:', error.message);
            }
        }
    }

    async testWebSocketConnection() {
        console.log('\n🔌 步骤2: WebSocket连接测试...');
        return new Promise((resolve, reject) => {
            try {
                const wsUrl = `ws://${CONFIG.server.host}:${CONFIG.server.port}/user-service/websocket?t=${this.token}`;
                this.ws = new WebSocket(wsUrl);
                this.ws.on('open', async () => {
                    console.log('✅ WebSocket连接成功');
                    this.setupMessageHandler();
                    await this.delay(500);
                    resolve();
                });
                this.ws.on('error', (error) => {
                    console.log('❌ WebSocket连接失败:', error.message);
                    reject(error);
                });
                this.ws.on('close', () => {
                    console.log('🔌 WebSocket连接已关闭');
                });
                setTimeout(() => {
                    if (this.ws.readyState === WebSocket.CONNECTING) {
                        this.ws.close();
                        reject(new Error('连接超时'));
                    }
                }, 10000);
            } catch (error) {
                reject(error);
            }
        });
    }

    setupMessageHandler() {
        this.ws.on('message', (data) => {
            try {
                const msg = JSON.parse(data.toString());
                console.log('📨 收到消息:', JSON.stringify(msg, null, 2));
            } catch (_) { }
        });
    }

    async sendAndWait(actId, payload = {}, timeoutMs = 10000) {
        return new Promise((resolve, reject) => {
            const timer = setTimeout(() => {
                this.ws?.off?.('message', handler);
                reject(new Error(`等待act_id ${actId} 响应超时`));
            }, timeoutMs);
            const handler = (raw) => {
                try {
                    const msg = JSON.parse(raw.toString());
                    if (msg && msg.act_id === actId) {
                        clearTimeout(timer);
                        this.ws.off('message', handler);
                        resolve(msg);
                    }
                } catch (_) { }
            };
            this.ws.on('message', handler);
            const out = { c: actId, d: Object.keys(payload).length ? payload : null };
            this.ws.send(JSON.stringify(out));
        });
    }

    async testQueryCharacters() {
        console.log('\n📋 步骤3: 查询角色列表...');
        if (!this.ws || this.ws.readyState !== WebSocket.OPEN) {
            console.log('❌ WebSocket未连接');
            return;
        }
        await this.delay(1000);
        return new Promise((resolve) => {
            const responseHandler = (data) => {
                try {
                    const message = JSON.parse(data.toString());
                    if (message.act_id === 3) {
                        this.ws.removeListener('message', responseHandler);
                        const list = message.roleList && Array.isArray(message.roleList) ? message.roleList : [];
                        this.characters = list;
                        if (list.length) {
                            console.log(`✅ 查询成功，共${message.roleCount || list.length}个角色`);
                        } else {
                            console.log('✅ 查询成功，暂无角色');
                        }
                        resolve();
                    }
                } catch (_) {
                    this.ws.removeListener('message', responseHandler);
                    resolve();
                }
            };
            this.ws.on('message', responseHandler);
            this.ws.send(JSON.stringify({ c: 3, d: null }));
            setTimeout(() => {
                this.ws.removeListener('message', responseHandler);
                console.log('⚠️ 查询角色列表超时');
                resolve();
            }, 10000);
        });
    }

    async testCreateCharacter() {
        console.log('\n🧍 步骤4: 创建角色(无角色时)...');
        const payload = {
            c: 5,
            d: {
                name: CONFIG.testCharacter.name,
                sex: CONFIG.testCharacter.sex,
                roleType: CONFIG.testCharacter.roleType,
                headIndex: CONFIG.testCharacter.headIndex
            }
        };
        await this.sendRaw(payload);
        await this.delay(1000);
        console.log('✅ 创建角色请求已发送');
    }

    async sendRaw(obj) {
        this.ws.send(JSON.stringify(obj));
    }

    async testSelectCharacter() {
        console.log('\n🎯 步骤5: 选择角色...');
        const roleId = this.characters[0]?.id;
        if (!roleId) {
            console.log('❌ 无可用角色');
            return;
        }
        return new Promise((resolve) => {
            const responseHandler = (data) => {
                try {
                    const message = JSON.parse(data.toString());
                    if (message.act_id === 4) {
                        this.ws.removeListener('message', responseHandler);
                        if (message.code === 0) {
                            this.selectedCharacter = { id: roleId };
                            console.log(`✅ 角色选择成功: ID=${roleId}`);
                        } else {
                            console.log('❌ 角色选择失败:', message.msg || message);
                        }
                        resolve();
                    }
                } catch (_) {
                    this.ws.removeListener('message', responseHandler);
                    resolve();
                }
            };
            this.ws.on('message', responseHandler);
            this.ws.send(JSON.stringify({ c: 4, d: { characterId: roleId } }));
            setTimeout(() => {
                this.ws.removeListener('message', responseHandler);
                console.log('⚠️ 选择角色超时');
                resolve();
            }, 10000);
        });
    }

    async testQueryChibiInfo(print = false) {
        console.log('\n📊 步骤6: 查询赤壁当前信息(4430)...');
        const info = await this.sendAndWait(4430, {});
        if (info.code !== 0) throw new Error(info.msg || '查询赤壁信息失败');
        this.currentInfo = info.data;
        if (print) console.log('📨 4430返回:', info);
        console.log(`✅ 当前期数: ${this.currentInfo?.curRndNum}, 剩余秒数: ${this.currentInfo?.second}`);
    }

    async testChibiBet() {
        console.log('\n🎲 步骤7: 下注(4437)...');
        const res = await this.sendAndWait(4437, { side: '1', type: '1', bet: '100' });
        if (res.code !== 0) throw new Error(res.msg || '下注失败');
        console.log('✅ 下注成功');
        await this.delay(200);
    }

    async testDisconnect() {
        console.log('\n🔌 步骤8: 断开连接...');
        try { this.ws?.close?.(); } catch (_) { }
        console.log('✅ 完成');
    }

    // 工具函数
    async makeHttpRequest(path, method = 'GET', body = null) {
        const options = {
            hostname: CONFIG.server.host,
            port: CONFIG.server.port,
            path,
            method,
            headers: { 'Content-Type': 'application/json' }
        };
        return new Promise((resolve, reject) => {
            const req = http.request(options, (res) => {
                let data = '';
                res.on('data', (chunk) => (data += chunk));
                res.on('end', () => {
                    try {
                        const json = JSON.parse(data || '{}');
                        if (res.statusCode >= 200 && res.statusCode < 300) {
                            resolve(json);
                        } else {
                            const err = new Error(json?.msg || `HTTP ${res.statusCode}`);
                            reject(err);
                        }
                    } catch (error) {
                        reject(new Error('响应解析失败'));
                    }
                });
            });
            req.on('error', (err) => reject(err));
            if (body) req.write(JSON.stringify(body));
            req.end();
        });
    }

    delay(ms) { return new Promise((r) => setTimeout(r, ms)); }
}

(async () => {
    const tester = new Code4437Tester();
    await tester.runTest();
})();